home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / ircii2-6.zip / SRC\IRCII-2.6\SOURCE\SCANDIR.C < prev    next >
C/C++ Source or Header  |  1994-12-29  |  7KB  |  264 lines

  1. #ifndef lint
  2. static    char    rcsid[] = "@(#)$Id: scandir.c,v 1.24 1994/10/08 16:50:35 mrg Stab $";
  3. #endif
  4.  
  5. #include "defs.h"
  6.  
  7. #ifndef HAVE_SCANDIR
  8. #if (!defined(ultrix) && !defined(__386BSD__) && !defined(_HPUX_SOURCE)) || defined(HPUX7)
  9.  
  10. /*
  11.  * Copyright (c) 1983 Regents of the University of California. All rights
  12.  * reserved. 
  13.  *
  14.  * Redistribution and use in source and binary forms are permitted provided that
  15.  * the above copyright notice and this paragraph are duplicated in all such
  16.  * forms and that any documentation, advertising materials, and other
  17.  * materials related to such distribution and use acknowledge that the
  18.  * software was developed by the University of California, Berkeley.  The
  19.  * name of the University may not be used to endorse or promote products
  20.  * derived from this software without specific prior written permission. THIS
  21.  * SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  22.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  23.  * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
  24.  */
  25.  
  26. # if defined(LIBC_SCCS) && !defined(lint)
  27. static char sccsid[] = "@(#)scandir.c    5.3 (Berkeley) 6/18/88";
  28. # endif /* LIBC_SCCS and not lint */
  29.  
  30. # define NULL 0
  31.  
  32. /*
  33.  * Scan the directory dirname calling select to make a list of selected
  34.  * directory entries then sort using qsort and compare routine dcomp. Returns
  35.  * the number of entries and a pointer to a list of pointers to struct direct
  36.  * (through namelist). Returns -1 if there were any errors. 
  37.  */
  38.  
  39. /*
  40.  * Mike Sandrof added this for HPUX compatibility in
  41.  * IRCII on the advice of some HPUX users - 5/11/90 
  42.  * this is no longer valid, as hpux has its own scandir(), june 1993, phone.
  43.  * at least, for some versions of hpux.. oct 1994, mrg.
  44.  *
  45.  * Brett Sivies added POSIX here.
  46.  */
  47.  
  48. # if defined(XD88) || defined(__svr4__) || defined(POSIX) || defined(__linux__) \
  49.   || defined(SVR3) || defined(__osf__) || defined(M_UNIX) || defined(_SEQUENT_) \
  50.   || defined(__QNX__) || defined(__BORLANDC__)
  51. /*
  52. **  SCANDIR
  53. **  Scan a directory, collecting all (selected) items into a an array.
  54. */
  55. # ifndef __BORLANDC__
  56. #  include <stdio.h>
  57. #  include <sys/types.h>
  58. #  include <dirent.h>
  59. #  include <sys/file.h>
  60. #  ifdef XD88
  61. #   include <sys/unistd.h>
  62. #  else
  63. #   include <unistd.h>
  64. #  endif /* XD88 */
  65. # else
  66. #  include "irc.h"
  67. #  include <dirent.h>
  68. # endif
  69.  
  70.  
  71. /* Initial guess at directory size. */
  72. # define INITIAL_SIZE    30
  73.  
  74. # ifndef DIRSIZ
  75. #  define DIRSIZ(d) (sizeof(struct dirent) + strlen(d->d_name) + 1) 
  76. # endif
  77.  
  78. /* Linked in later. */
  79. extern char        *new_malloc();
  80. extern char        *new_realloc();
  81. extern char        *strcpy();
  82.  
  83. int
  84. scandir(Name, List, Selector, Sorter)
  85. #if defined(__linux__) || defined(__sgi)
  86.     const char            *Name;
  87. #else
  88.     char          *Name;
  89. #endif
  90.     struct dirent        ***List;
  91.     int             (*Selector)();
  92.     int             (*Sorter)();
  93. {
  94.     struct dirent     **names;
  95.     static  struct dirent      *E;
  96.     register DIR      *Dp;
  97.     register int       i;
  98.     register int       size = INITIAL_SIZE;
  99.  
  100.     if (!(names = (struct dirent **) new_malloc(size * sizeof names[0])) || access(Name, R_OK | X_OK) || !(Dp = opendir(Name)))
  101.     return(-1);
  102.  
  103.     /* Read entries in the directory. */
  104.  
  105.     for (i = 0; (E = readdir(Dp)); )
  106.     if (Selector == NULL || (*Selector)(E))
  107.     {
  108.         /* User wants them all, or he wants this one. */
  109.         if (++i >= size)
  110.         {
  111.         size <<= 1;
  112.         names = (struct dirent **) new_realloc((char *)names, size * sizeof names[0]);
  113.         if (names == NULL)
  114.         {
  115.             closedir(Dp);
  116.             new_free(&names);
  117.             return(-1);
  118.         }
  119.         }
  120.  
  121.         /* Copy the entry. */
  122.         if ((names[i - 1] = (struct dirent *) new_malloc(DIRSIZ(E))) == NULL)
  123.         { 
  124.         closedir(Dp);
  125.         new_free(&names);
  126.         return(-1);
  127.         }
  128. #if !defined(__QNX__) && !defined(__BORLANDC__)
  129.         names[i - 1]->d_ino = E->d_ino;
  130.         names[i - 1]->d_reclen = E->d_reclen;
  131. #endif
  132.         (void) strcpy(names[i - 1]->d_name, E->d_name);
  133.     }
  134.  
  135.     /* Close things off. */
  136.     names = (struct dirent **) new_realloc((char *) names, (i + 1) * sizeof names[0]);
  137.     names[i] = 0;
  138.     *List = names;
  139.     closedir(Dp);
  140.  
  141.     /* Sort? */
  142.     if (i && Sorter)
  143.     qsort((char *)names, i, sizeof names[0], Sorter);
  144.  
  145.     return(i);
  146. }
  147. #else
  148. # include <sys/types.h>
  149. # include <sys/stat.h>
  150. # include <sys/file.h>
  151. # include "irc.h"
  152. # if defined(ISC22) || defined(ESIX) || defined(HPUX7)
  153. #  ifdef ESIX
  154. #   include <dirent.h>
  155. #  else
  156. #   include <sys/dirent.h>
  157. #  endif /* ESIX */
  158. #  undef DIRSIZ
  159. #  if defined(ISC22) || defined(ESIX)
  160. #   define DIRSIZ(dp) \
  161.     (( sizeof( struct dirent) + (strlen(dp->d_name)+1) ))
  162. #  else
  163. #   define DIRSIZ(dp) \
  164.     ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1+3)&~ 3))
  165. #  endif /* defined(ISC22) || defined(ESIX) */
  166. #  define direct dirent
  167. # else
  168. #  include <sys/dir.h>
  169. # endif /* defined(ISC22) || defined(ESIX) */
  170. /* End of Mike Sandrof's change */
  171.  
  172.  
  173. int scandir(dirname, namelist, select, dcomp)
  174. #ifdef NeXT
  175. const char *dirname;
  176. #else
  177. char *dirname;
  178. #endif /* NeXT */
  179. struct direct *(*namelist[]);
  180. int (*select) (), (*dcomp) ();
  181. {
  182.     register struct direct *d,
  183.           *p,
  184.          **names;
  185.     register int nitems;
  186.     register char *cp1,
  187.         *cp2;
  188.     struct stat stb;
  189.     long arraysz;
  190.     DIR *dirp;
  191.  
  192.     if (access(dirname, R_OK|X_OK))
  193.     return (-1);
  194.     if ((dirp = opendir(dirname)) == NULL)
  195.     return (-1);
  196.     if (fstat(dirp->dd_fd, &stb) < 0)
  197.     return (-1);
  198.  
  199.     /*
  200.      * estimate the array size by taking the size of the directory file and
  201.      * dividing it by a multiple of the minimum size entry. 
  202.      */
  203.     arraysz = (stb.st_size / 24);
  204.     names = (struct direct **) new_malloc(arraysz * sizeof(struct direct *));
  205.     if (names == NULL)
  206.     return (-1);
  207.  
  208.     nitems = 0;
  209.     while ((d = readdir(dirp)) != NULL)
  210.     {
  211.     if (select != NULL && !(*select) (d))
  212.         continue;        /* just selected names */
  213.     /*
  214.      * Make a minimum size copy of the data 
  215.      */
  216.     p = (struct direct *) new_malloc(DIRSIZ(d));
  217.     if (p == NULL)
  218.         return (-1);
  219. #if !defined(__BORLANDC__)
  220.     p->d_ino = d->d_ino;
  221.     p->d_reclen = d->d_reclen;
  222. #endif
  223. # if ! defined(ISC22) && ! defined(ESIX)
  224.     p->d_namlen = d->d_namlen;
  225. # endif /* ! defined(ISC22) && ! defined(ESIX) */
  226.     for (cp1 = p->d_name, cp2 = d->d_name; *cp1++ = *cp2++;);
  227.     /*
  228.      * Check to make sure the array has space left and realloc the
  229.      * maximum size. 
  230.      */
  231.     if (++nitems >= arraysz)
  232.     {
  233.         if (fstat(dirp->dd_fd, &stb) < 0)
  234.         return (-1);    /* just might have grown */
  235.         arraysz = stb.st_size / 12;
  236.         names = (struct direct **) new_realloc((char *) names,
  237.                      arraysz * sizeof(struct direct *));
  238.         if (names == NULL)
  239.         return (-1);
  240.     }
  241.     names[nitems - 1] = p;
  242.     }
  243.     closedir(dirp);
  244.     if (nitems && dcomp != NULL)
  245.     qsort(names, nitems, sizeof(struct direct *), dcomp);
  246.     *namelist = names;
  247.     return (nitems);
  248. }
  249.  
  250.  
  251. /*
  252.  * Alphabetic order comparison routine for those who want it. 
  253.  */
  254. int alphasort(d1, d2)
  255. struct direct **d1,
  256.      **d2;
  257. {
  258.     return (strcmp((*d1)->d_name, (*d2)->d_name));
  259. }
  260. #endif
  261.  
  262. #endif    /* ultrix || __386BSD__ || BSD */
  263. #endif /* !HAVE_SCANDIR */
  264.